package com.googlecode.framework.core.bean;

import java.util.LinkedList;
import java.util.List;

import org.springframework.util.CollectionUtils;

/**
 * 方便处理LabelValueBean的工具类
 * 
 * @author xiayg
 * 
 */
public class LabelValueBeanHelper {

    public static final String LABEL_NOSELECT = "---请选择---";

    private LabelValueBeanHelper() {
    }

    /**
     * 创建一个空的列表
     * @param vClazz 值类型
     * @return
     */
    public static <V> List<LabelValueBean<V>> empty(Class<V> vClazz) {
        return empty(vClazz, false);
    }

    /**
     * 创建一个空的列表
     * @param vClazz 值类型
     * @param empty 是否包含请选择的选项
     * @return
     */
    public static <V> List<LabelValueBean<V>> empty(Class<V> vClazz, boolean empty) {
        List<LabelValueBean<V>> list = new LinkedList<LabelValueBean<V>>();
        if (empty) {
            list.add(createLabelValue(vClazz, null));
        }
        return list;
    }
    
    /**
     * 创建一个空的列表
     * @param vClazz 值类型
     * @param empty 是否包含请选择的选项
     * @param emptyValue 请选择的选项对应的值
     * @return
     */
    public static <V> List<LabelValueBean<V>> empty(Class<V> vClazz, boolean empty, V emptyValue) {
        List<LabelValueBean<V>> list = new LinkedList<LabelValueBean<V>>();
        if (empty) {
            list.add(createLabelValue(vClazz, emptyValue));
        }
        return list;
    }

    /**
     * 创建一个请选择选项对应的LabelValueBean
     * 
     * @param vClazz 值类型
     * @param emptyValue 请选择的选项对应的值
     * @return
     */
    public static <V> LabelValueBean<V> createLabelValue(Class<V> vClazz, V emptyValue) {
        LabelValueBean<V> lvbEmpty = new LabelValueBean<V>(LABEL_NOSELECT, emptyValue);
        return lvbEmpty;
    }
    
    /**
     * 在原来的列表中添加请选择的选项
     * @param vClazz 值类型
     * @param lvbs 原来的列表
     * @return
     */
    public static <V> List<LabelValueBean<V>> addEmpty(Class<V> vClazz, List<LabelValueBean<V>> lvbs) {
        return addEmpty(vClazz, null, lvbs);
    }
    
    /**
     * 在原来的列表中添加请选择的选项
     * @param vClazz 值类型
     * @param emptyValue 请选择的选项对应的值
     * @param lvbs 原来的列表
     * @return
     */
    public static <V> List<LabelValueBean<V>> addEmpty(Class<V> vClazz, V emptyValue, List<LabelValueBean<V>> lvbs) {
        List<LabelValueBean<V>> lvbsToUse = empty(vClazz, true, emptyValue);
        if (!CollectionUtils.isEmpty(lvbs)) {
            lvbsToUse.addAll(lvbs);
        }
        return lvbsToUse;
    }
    
    /**
     * 将一个JavaBean的List转换成一个LabelValueBean的List
     * 
     * @param vClazz 值类型
     * @param beanList 原先的Bean List
     * @param creator LabelValueBeanCreator
     * @return
     */
    public static <B, V> List<LabelValueBean<V>> convert(Class<V> vClazz, List<B> beanList, 
            LabelValueBeanCreator<B, V> creator) {
        return convert(vClazz, false, null, beanList, creator);
    }
    
    /**
     * 将一个JavaBean的List转换成一个LabelValueBean的List
     * @param vClazz 值类型
     * @param empty 是否包含请选择的选项
     * @param beanList 原先的Bean List
     * @param creator LabelValueBeanCreator
     * @return
     */
    public static <B, V> List<LabelValueBean<V>> convert(Class<V> vClazz, boolean empty,
            List<B> beanList, LabelValueBeanCreator<B, V> creator) {
        return convert(vClazz, empty, null, beanList, creator);
    }    
    
    /**
     * 将一个JavaBean的List转换成一个LabelValueBean的List
     * @param vClazz 值类型
     * @param empty 是否包含请选择的选项
     * @param emptyValue 请选择的选项对应的值
     * @param beanList 原先的Bean List
     * @param creator LabelValueBeanCreator
     * @return
     */
    public static <B, V> List<LabelValueBean<V>> convert(Class<V> vClazz, boolean empty, V emptyValue,
            List<B> beanList, LabelValueBeanCreator<B, V> creator) {
        List<LabelValueBean<V>> lvbsToUse = empty(vClazz, empty, emptyValue);
        if (CollectionUtils.isEmpty(beanList)) {
            return lvbsToUse;
        }
        
        for (B o : beanList) {
            lvbsToUse.add(new LabelValueBean<V>(creator.getLabel(o), creator.getValue(vClazz, o)));
        }
        return lvbsToUse;
    }    

    /*
     * LabelValueBean生成器
     */
    public static interface LabelValueBeanCreator<K, V> {
        String getLabel(K obj);

        V getValue(Class<V> valueClass, K obj);
    }
}
